import axios from 'axios'
import { ElMessage } from 'element-plus'
import router from '@/router'
import { useUserStore } from '@/store/user'
import { useFrontUserStore } from '@/store/frontUser'

// 创建axios实例
const service = axios.create({
  baseURL: '', // 保持为空，使用相对路径可以通过代理转发
  timeout: 15000 // 请求超时时间
})

// 上次未授权处理的时间戳，用于防止重复处理
let lastUnauthorizedTime = null

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 为PUT请求添加特殊日志
    if (config.method === 'put') {
      console.group('PUT请求详情')
      console.log('PUT请求URL:', config.url)
      console.log('PUT请求头:', config.headers)
      console.log('PUT请求数据:', config.data)
      console.groupEnd()
    }

    // 判断是否是前台API请求
    const url = config.url || ''
    const isFrontRequest = url.includes('/api/front/') || url.includes('/front/api/')
    
    // 检查是否需要匿名访问
    const forceAnonymous = config.params && config.params.anonymous === true
    if (forceAnonymous) {
      console.log('强制匿名访问:', url)
      config.headers['X-Anonymous-Access'] = 'true'
      // 移除可能的认证头
      delete config.headers['Authorization']
      delete config.headers['satoken']
      
      // 从参数中移除匿名标记，避免传递给后端
      if (config.params) {
        const { anonymous, ...restParams } = config.params
        config.params = restParams
      }
      
      return config
    }
    
    // 根据请求类型选择不同的token
    let token = null
    if (isFrontRequest) {
      // 前台API请求使用frontToken
      token = localStorage.getItem('frontToken')
      console.log('前台API请求:', url, token ? '已认证' : '匿名访问')
      
      // 前台API不存在token时，添加匿名访问标记
      if (!token) {
        config.headers['X-Anonymous-Access'] = 'true'
      }
    } else {
      // 后台API请求使用普通token
      token = localStorage.getItem('token')
      console.log('后台API请求:', url)
    }
    
    // 如果token存在，添加到请求头
    if (token) {
      // 添加到Authorization头
      config.headers['Authorization'] = token
      // 保留satoken头以兼容后端
      config.headers['satoken'] = token
    } else if (!isFrontRequest && !url.includes('/api/auth/login')) {
      // 非前台请求且非登录请求缺少token时记录警告
      console.warn('后台请求缺少token:', url)
    }
    
    return config
  },
  error => {
    console.error('请求错误', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  /**
   * 如果您想获取诸如头或状态之类的http信息
   * 请返回response => response
   */

  /**
   * 通过自定义代码确定请求状态
   * 这里只是一个例子
   * 您还可以通过HTTP状态代码判断状态
   */
  response => {
    // 打印API响应用于调试
    console.group(`API响应: ${response.config.url}`)
    console.log('请求URL:', response.config.url)
    console.log('请求方法:', response.config.method)
    console.log('请求参数:', response.config.params || {})
    console.log('响应状态:', response.status)
    console.log('响应数据:', response.data)
    console.groupEnd()
    
    // 请求成功处理
    const res = response.data
    
    // 如果响应不成功，则根据状态码处理
    if (res.code !== 20000 && res.code !== 200 && res.code !== 0) {
      // 针对401错误处理 - 登录过期或未授权
      if (res.code === 401 || res.code === 10401) {
        console.warn('API响应显示未授权(401)，调用handleUnauthorized')
        handleUnauthorized(response.config.url)
      }
      
      // 对于403无权限请求，给出明确提示
      if (res.code === 403 || res.code === 10403) {
        ElMessage({
          message: res.message || '您没有操作权限',
          type: 'error',
          duration: 5 * 1000
        })
      }
      
      return res
    } else {
      return res
    }
  },
  error => {
    console.error('请求响应错误', error)
    
    // 区分404错误与其他错误
    if (error.response && error.response.status === 404) {
      console.warn('资源不存在(404)，请检查API路径:', error.config.url)
      
      // 如果是前台API请求404，静默处理，避免影响用户体验
      if (error.config && error.config.url && error.config.url.includes('/api/front')) {
        console.log('前台API 404错误，静默处理')
        return Promise.reject({
          message: '资源未找到',
          status: 404,
          silent: true,
          originalError: error
        })
      }
    }
    
    // 处理401错误 - 登录过期或未授权
    if (error.response && error.response.status === 401) {
      console.warn('HTTP响应401未授权，调用handleUnauthorized')
      handleUnauthorized(error.config.url)
      return Promise.reject(error)
    }
    
    // 处理其他错误类型 - 网络错误、超时等
    const errorMessage = getErrorMessage(error)
    
    // 避免错误消息堆积
    setTimeout(() => {
      // 显示错误提示
      ElMessage({
        message: errorMessage,
        type: 'error',
        duration: 5000
      })
    }, 100)
    
    return Promise.reject(error)
  }
)

/**
 * 根据错误类型获取友好的错误消息
 */
function getErrorMessage(error) {
  if (error.message.includes('timeout')) {
    return '请求超时，请稍后再试'
  } else if (error.message.includes('Network Error')) {
    return '网络连接错误，请检查您的网络'
  } else if (error.response) {
    // 根据HTTP状态码返回不同的错误消息
    switch(error.response.status) {
      case 400: return '请求参数错误'
      case 403: return '您没有权限进行此操作'
      case 404: return '请求的资源不存在'
      case 500: return '服务器内部错误'
      case 502: return '网关错误'
      case 503: return '服务不可用'
      default: return `请求失败 (${error.response.status})`
    }
  } else {
    return '请求发生错误，请稍后再试'
  }
}

/**
 * 处理未授权（401）情况
 * @param {string} url - 请求URL
 */
function handleUnauthorized(url) {
  const currentTime = Date.now()
  const currentRoute = router.currentRoute.value
  
  // 防止短时间内多次触发
  if (lastUnauthorizedTime && currentTime - lastUnauthorizedTime < 3000) {
    console.log('短时间内已处理过未授权请求，跳过处理')
    return
  }
  
  // 记录本次处理时间
  lastUnauthorizedTime = currentTime
  
  console.log('处理未授权请求:', url, '当前路由:', currentRoute.path)
  
  // 判断是否是前台API
  const isFrontApi = url.includes('/api/front/')
  
  if (isFrontApi) {
    // 前台API未授权处理
    clearFrontTokens()
    
    // 只有当前路由需要前台登录时才提示并跳转
    if (currentRoute.meta?.requiresFrontAuth) {
      ElMessage({
        message: '您的登录已过期，请重新登录',
        type: 'warning',
        duration: 3000
      })
      
      // 跳转到前台登录页，并传递当前页面作为重定向目标
      router.push({
        path: '/front/login',
        query: { redirect: currentRoute.fullPath }
      })
    } else {
      console.log('前台API未授权，但当前页面不需要登录，静默处理')
    }
  } else {
    // 后台API未授权处理
    clearAdminTokens()
    
    // 如果当前在管理后台，才提示并跳转
    if (!currentRoute.path.startsWith('/front') && currentRoute.path !== '/') {
      ElMessage({
        message: '您的管理登录已过期，请重新登录',
        type: 'warning',
        duration: 3000
      })
      
      // 跳转到管理登录页
      router.push({
        path: '/login',
        query: { redirect: currentRoute.fullPath }
      })
    } else {
      console.log('后台API未授权，但当前在前台页面，静默处理')
    }
  }
}

/**
 * 清除前台令牌和用户信息
 */
function clearFrontTokens() {
  const frontUserStore = useFrontUserStore()
  frontUserStore.resetState() // 使用重置方法，确保完全清除
  localStorage.removeItem('frontToken')
  localStorage.removeItem('frontUserInfo')
  console.log('已清除前台登录信息')
}

/**
 * 清除管理后台令牌和用户信息
 */
function clearAdminTokens() {
  const userStore = useUserStore()
  userStore.setToken('')
  userStore.setUser(null)
  localStorage.removeItem('token')
  localStorage.removeItem('user')
  localStorage.removeItem('refreshToken')
  localStorage.removeItem('userInfo')
  console.log('已清除后台登录信息')
}

// 用于跟踪最近处理的token过期URL，防止重复处理
const recentlyHandledUrls = {
  front: { timestamp: 0, url: '' },
  admin: { timestamp: 0, url: '' }
}

// 检查是否已经处理过token过期
const checkTokenHandled = (url, type) => {
  const now = Date.now()
  const lastHandled = recentlyHandledUrls[type]
  
  // 如果在最近5秒内已经处理过相同类型的token过期，不重复处理
  if (now - lastHandled.timestamp < 5000) {
    console.log(`已在5秒内处理过${type}类型的token过期，不重复处理`, url)
    return true
  }
  
  // 更新处理记录
  recentlyHandledUrls[type] = { timestamp: now, url: url }
  return false
}

export default service 